package com.qunar.qcf.handler.transport;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import org.reflections.Reflections;

import com.qunar.qcf.handler.InvokeHandler;
import com.qunar.qcf.handler.annotation.Handler;
import com.qunar.qcf.handler.annotation.Remote;

public class QCFInit {

	public static void register(Map<String, InvokeHandler> handlers, Map<String, Method> initMethods) {
		register(handlers, initMethods, Handler.class);
	}

	public static void register(Map<String, InvokeHandler> handlers, Map<String, Method> initMethods, Class<?> annClass) {
		try {
			Reflections reflections = new Reflections("com.qunar");
			Set<Class<?>> annotated = reflections.getTypesAnnotatedWith((Class<? extends Annotation>) annClass);
			Iterator<Class<?>> it = annotated.iterator();
			while (it.hasNext()) {
				Class<?> next = it.next();
				if (next.isAnnotationPresent(Handler.class)) {
					Annotation ann = (Annotation) next.getAnnotation((Class<? extends Annotation>) annClass);
					handlers.put(((Handler) ann).name(), (InvokeHandler) next.newInstance());

					Method[] methods = next.getDeclaredMethods();
					for (Method method : methods) {
						if (method.isAnnotationPresent(Remote.class)) {
							Remote path = method.getAnnotation(Remote.class);
							initMethods.put(((Handler) ann).name() + path.url(), method);
						}
					}

				}
			}
		} catch (Exception e) {
			new ExceptionInInitializerError(e);
		}
	}


}
